package cn.regexp.demo.ui;

import cn.regexp.demo.entity.University;
import cn.regexp.demo.util.UniversityDataUtils;
import com.google.common.collect.Lists;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.table.TableView;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.util.List;

/**
 * @author Regexpei
 * @date 2024/6/23 15:37
 * @description 大学列表面板
 */
public class UniversityListPanel extends JPanel {

    /**
     * 表格视图
     */
    private final TableView<University> table;

    /**
     * 滚动条面板
     */
    private final JScrollPane scrollPane;

    private final List<University> universities;


    public UniversityListPanel() {
        initUI();
        this.universities = Lists.newArrayList();

        this.table = new TableView<>();
        // 设置列表单选
        table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        // 为表格创建滚动条
        this.scrollPane = ScrollPaneFactory.createScrollPane(table);
        // 滚动面板监听事件，当滚动条发生调整，根据滚动位置加载更多内容
        this.scrollPane.getVerticalScrollBar().addAdjustmentListener(e -> {
            // 计算滚动条的下边界 = 滚动条可见长度 + 滚动条当前位置
            int lowerEnd = e.getAdjustable().getVisibleAmount() + e.getAdjustable().getValue();
            // 判断下边界是否达到滚动条的最大值，即是否需要加载更多数据
            if (lowerEnd == e.getAdjustable().getMaximum()) {
                addUniversities(UniversityDataUtils.getNextPage());
            }
        });
        // 将滚动面板添加到面板中
        add(this.scrollPane);

        // 更新表格数据
        updateModel(this.universities);
    }

    @SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
    private void initUI() {
        setLayout(new BorderLayout());
    }

    private void updateModel(List<University> universities) {
        // 将数据填充到表格中
        this.table.getListTableModel().addRows(universities);
    }

    public void setUniversities(List<University> universities) {
        this.universities.clear();
        this.universities.addAll(universities);

        table.setModelAndUpdateColumns(new ListTableModel<>(generateColumnsInfo(), this.universities, 0));
        table.repaint();
    }

    public void addUniversities(@NotNull List<University> universities) {
        this.universities.addAll(universities);
        // 减少滚动条的值以向下滚动 scrollPane 的内容（貌似去掉也可以？）
        scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getValue() - 1);
    }

    @SuppressWarnings("rawtypes")
    private ColumnInfo[] generateColumnsInfo() {
        List<ColumnInfo<University, Object>> columnList = Lists.newArrayList();
        columnList.add(new ColumnInfo<>("ID") {
            @Override
            public @Nullable Object valueOf(University university) {
                return university.getId();
            }
        });
        columnList.add(new ColumnInfo<>("校名") {
            @Override
            public @Nullable Object valueOf(University university) {
                return university.getName();
            }
        });
        columnList.add(new ColumnInfo<>("省份") {
            @Override
            public @Nullable Object valueOf(University university) {
                return university.getProvince();
            }
        });
        columnList.add(new ColumnInfo<>("城市") {
            @Override
            public @Nullable Object valueOf(University university) {
                return university.getCity();
            }
        });
        columnList.add(new ColumnInfo<>("985") {
            @Override
            public @NotNull Object valueOf(University university) {
                return university.getF985() == 1 ? "√" : "";
            }
        });
        columnList.add(new ColumnInfo<>("211") {
            @Override
            public @NotNull Object valueOf(University university) {
                return university.getF211() == 1 ? "√" : "";
            }
        });
        columnList.add(new ColumnInfo<>("性质") {
            @Override
            public @Nullable Object valueOf(University university) {
                return university.getNature();
            }
        });

        return columnList.toArray(new ColumnInfo[0]);
    }

}
